package com.gitee.wsl.transform.parser.string

import com.gitee.wsl.transform.parser.Parser
import com.gitee.wsl.transform.parser.ParserString
import com.gitee.wsl.transform.parser.StringParser

/**
 * Parses whitespace ' ' (space), '\t' tab or '\n'.
 * This operation never fails. For empty text, simple returns empty list of chars.
 */
fun Parser.Companion.whitespace(): StringParser<List<Char>> = zeroOrMany(sat { it.isWhitespace() })

/**
 * Parses a thing and then removes the whitespace after it.
 *
 * **Example**
 * ```
 * val parser = token(string("okay"))
 * parser("okay Google")
 * // ParserResult(value="okay", leftover = "Google")
 * ```
 */
fun <T> Parser.Companion.token(parser: StringParser<T>): StringParser<T> = parser.flatMap { t ->
    whitespace().flatMap {
        pure(t)
    }
}

/**
 * Parses a string and then remove the whitespace after it.
 * See [token].
 */
fun Parser.Companion.symbolicToken(str: String): StringParser<String> = token(string(str))


fun Parser.Companion.takeAllLeft(): ParserString = takeWhile { true }

fun Parser.Companion.takeWhile(predicate: (Char) -> Boolean): ParserString =
    zeroOrMany(sat(predicate)).flatMap {
        pure(it.joinToString(separator = ""))
    }